#include <iostream>
#include <pthread.h>
#include <queue>
#include <memory>
#include <unistd.h>


// 定义基础事件类
class Event
{
public:
    using ptr = std::shared_ptr<Event>;
    virtual ~Event() = default;
    virtual void Handle() = 0;
};

// 实例事件
class MousePressEvent : public Event
{
public:
    using ptr = std::shared_ptr<MousePressEvent>;
    MousePressEvent(int x, int y)
        : _x(x), _y(y)
    {}

    void Handle() override
    {
        std::cout << "Mouse clicked at (" << _x << ", " << _y << ")\n";
    }
private:
    int _x;
    int _y;
};

class KeyEvent : public Event
{
public:
    using ptr = std::shared_ptr<KeyEvent>;
    KeyEvent(char key) : _key(key)
    {}

    void Handle() override
    {
        std::cout << "Key pressed: " << _key << std::endl;
    }
private:
    char _key;
};



// 定义事件队列
class EventQueue
{
public:
    EventQueue(int capacity) : _capacity(capacity)
    {}

    void postEvent(Event::ptr event)
    {
        pthread_mutex_lock(&_mutex);
        while (_queue.size() == _capacity)
        {
            std::cout << "Event queue is full, producer is waiting..." << std::endl;
            pthread_cond_wait(&_not_full, &_mutex);
            pthread_cond_signal(&_not_empty);
        }
        _queue.push(event);
        pthread_mutex_unlock(&_mutex);

        pthread_cond_signal(&_not_empty);
    }

    Event::ptr takeEvent()
    {
        pthread_mutex_lock(&_mutex);
        while (_queue.size() == 0)
        {
            std::cout << "Event queue is empty, consumer is waiting..." << std::endl;
            pthread_cond_wait(&_not_empty, &_mutex);
            pthread_cond_signal(&_not_full);
        }
        Event::ptr event = _queue.front();
        _queue.pop();
        pthread_mutex_unlock(&_mutex);

        pthread_cond_signal(&_not_full);
        return event;
    }
private:
    std::queue<Event::ptr> _queue;
    int _capacity;
    pthread_mutex_t _mutex;
    pthread_cond_t _not_empty; // 通知消费者消费
    pthread_cond_t _not_full;  // 通知生产者生产
};

// 全局事件队列
EventQueue eventqueue(5);

// 生产者线程函数
void* Produce(void* args)
{
    int eventId = 0;
    while (true)
    {
        if (eventId % 2 == 0)
        {
            eventqueue.postEvent(std::make_shared<KeyEvent>('A' + eventId % 26));
        }
        else
        {
            eventqueue.postEvent(std::make_shared<MousePressEvent>((eventId+3)%10, (eventId+4)%10));
        }

        ++eventId;
        sleep(1);
    }
    return nullptr;
}

// 消费者线程函数
void* Consume(void* args)
{
    while (true)
    {
        Event::ptr event = eventqueue.takeEvent();
        event->Handle();
        sleep(2);
    }
    return nullptr;
}

int main()
{
    pthread_t producer, consumer;
    pthread_create(&producer, nullptr, Produce, nullptr);
    pthread_create(&consumer, nullptr, Consume, nullptr);

    pthread_join(producer, nullptr);
    pthread_join(consumer, nullptr);

    return 0;
}